package login

import (
	"crypto/tls"
	"fmt"

	"passport/errorcode"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/httplib"
	log "github.com/cihub/seelog"
)

type AuthorizeService struct{}

var (
	defaultAuthorizeService *AuthorizeService
)

func newAuthorizeService() *AuthorizeService {
	service := &AuthorizeService{}
	return service
}

func GetAuthorizeService() *AuthorizeService {
	if defaultAuthorizeService == nil {
		defaultAuthorizeService = newAuthorizeService()
	}
	return defaultAuthorizeService
}

//获取openid
type GetOpenidByCodeResp struct {
	Errcode      int    `json:"errcode"` //错误时返回的错误码和错误信息
	Errmsg       string `json:"errmsg"`
	AccessToken  string `json:"access_token"`
	ExpiresIn    int    `json:"expires_in"` //token失效时间，秒
	RefreshToken string `json:"refresh_token"`
	Openid       string `json:"openid"`
	Scope        string `json:"scope"` //授权作用域
}

//用户基本信息
type WeixinUserInfo struct {
	Errcode    int      `json:"errcode"` //错误时返回的错误码和错误信息
	Errmsg     string   `json:"errmsg"`
	Openid     string   `json:"openid"`
	Nickname   string   `json:"nickname"`
	Sex        int      `json:"sex"`
	Province   string   `json:"province"`
	City       string   `json:"city"`
	Country    string   `json:"country"`
	Headimgurl string   `json:"headimgurl"` //头像
	Privilege  []string `json:"privilege"`  //用户特权信息，json 数组
	Unionid    string   `json:"unionid"`    //	只有在用户将公众号绑定到微信开放平台帐号后，才会出现该字段。
}

func init() {
	GetAuthorizeService()
}

//获取openid
func (p *AuthorizeService) GetOpenidByCode(auCode string, h5Type int) (uint, string, *WeixinUserInfo) {
	//调用接口
	appid := beego.AppConfig.DefaultString("weixin::zjdj_open_appid", "")
	secret := beego.AppConfig.DefaultString("weixin::zjdj_openid_secretkey", "")

	if h5Type == 2 {
		appid = beego.AppConfig.DefaultString("weixin::qk_open_appid", "")
		secret = beego.AppConfig.DefaultString("weixin::qk_openid_secretkey", "")
	}

	reqURL := fmt.Sprintf("https://api.weixin.qq.com/sns/oauth2/access_token?")
	url := fmt.Sprintf("%sappid=%s&secret=%s&code=%s&grant_type=authorization_code", reqURL, appid, secret, auCode)
	b := httplib.Get(url)
	b.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
	resp := &GetOpenidByCodeResp{}
	if err := b.ToJSON(resp); err != nil {
		bytes, _ := b.Bytes()
		log.Errorf("根据code获取openid失败（连接微信失败），return:%s , err is : %s", string(bytes), err.Error())
		return errorcode.EC_AUTHORIZE_CONN_FAIL, "调用微信接口失败", nil
	}
	if resp.Errcode != 0 || resp.Errmsg != "" {
		log.Warnf("根据code获取openid失败（业务错误），err is : %d, msg:%s ", resp.Errcode, resp.Errmsg)
		return errorcode.EC_AUTHORIZE_ORTHER_ERR, "调微信其他业务错误", nil
	}
	log.Infof("授权获取openid成功！！")

	//获取用户基本信息
	info := p.GetWeixinUserInfo(resp.AccessToken, resp.Openid)
	if info.Errcode != 0 {
		return errorcode.EC_AUTHORIZE_ORTHER_ERR, "调微信其他业务错误", nil
	}

	return errorcode.EC_GL_SUCCESS, "成功", info
}

//根据微信的access_token和openid获取到用户信息
func (p *AuthorizeService) GetWeixinUserInfo(accessToken, openid string) *WeixinUserInfo {
	reqURL := fmt.Sprintf("https://api.weixin.qq.com/sns/userinfo?")
	url := fmt.Sprintf("%saccess_token=%s&openid=%s&lang=zh_CN ", reqURL, accessToken, openid)
	b := httplib.Get(url)
	b.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
	resp := &WeixinUserInfo{}
	if err := b.ToJSON(resp); err != nil {
		bytes, _ := b.Bytes()
		log.Errorf("获取用户信息失败（连接微信失败），return:%s ,err is : %s", string(bytes), err.Error())
		return resp
	}
	if resp.Errcode != 0 || resp.Errmsg != "" {
		log.Warnf("获取用户信息失败（业务错误），err is : %d, msg:%s ", resp.Errcode, resp.Errmsg)
		return resp
	}
	log.Infof("获取用户信息成功！！")
	return resp
}
